home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / LIBRARY / PBLIB1 / UNITS / PBMEMO.PAS < prev    next >
Pascal/Delphi Source File  |  1994-05-03  |  11KB  |  357 lines

  1. {SECTION ..PbMEMO }
  2. UNIT PbMEMO;
  3.  
  4. INTERFACE
  5.  
  6. uses PbMISC, PbOBJS, PbDBOBJ;
  7.  
  8. {
  9. Description : Dbase MEMO object
  10.  
  11. Author      : Howard Richoux
  12. Date        : 1/9/94
  13. Last revised: 2/18/94 NEW LIBRARIES
  14. Application : IBM PC and compatibles, done in Turbo Pascal 7
  15. Status      : Placed in the Public Domain by HNR Software 1/29/1994
  16. Published in: none
  17. }
  18.  
  19. {SECTION .MEMO_object }
  20.  
  21.  
  22. const mblksize = 512;
  23. type  MemoNdx     = longint;
  24. type  MEMObuftype = Array[1..mblksize] of byte;
  25.  
  26. type MEMO_object = object(BFILE_object)
  27.         mbuf     : MEMObuftype;
  28.         recs     : MemoNdx;
  29.         Procedure init    ( fname: string;  dbfmode  : integer);
  30.         Function  fetchN  ( ndx  : MemoNdx; var memo : STRA_object;
  31.                             var blocks : integer) : boolean;
  32.         Function  storeN  ( var memo : STRA_object; var ndx  : MemoNdx;
  33.                             var blocks : integer) : boolean;
  34.         Function  append  ( var memo : STRA_object; var ndx : MemoNdx;
  35.                             var blocks : integer) : boolean;
  36.         Function  MemoBlocksN ( ndx : MemoNdx) : integer;
  37.         Procedure ReadHeader;
  38.         Procedure UpdateHeader;
  39.         Procedure done;
  40.         end;
  41.  
  42.  
  43. Procedure PrepareSTRAforOutput(var memo : STRA_object);
  44.  
  45. {SECTION .ZIMPLEMENTATION }
  46. IMPLEMENTATION
  47. {Notes:
  48. From ALPHA4 v3 - memo block structure:                       I put on string
  49.  
  50.    $8D = soft CR for word wrap                                 $8D
  51.    $0D = hard CR shows as paragraph symbol                     nothing
  52.    $0A = line feed - terminates string                         nothing
  53.    $1A = end-of-MEMO marker                                    $FE
  54.  
  55. So if a STRA memo line ends in:
  56.    $8D the load buffer routine appends a $0A
  57. No $8D gets $8D $0A
  58. last line gets $FE --> $1A
  59.  
  60. }
  61.  
  62. {SECTION  LoadSTRAfromBuf }
  63. Procedure LoadSTRAfromBuf(var buf : MEMObuftype; var memo : STRA_object;
  64.                             var endflag : boolean; var s : string);
  65. { need to be handed an initialized STRA object, s can contain a partial
  66.    string from a previous buffer. Calling program sets s:= ''; first time}
  67. var i  : integer;
  68.     ok,done : boolean;
  69.      begin
  70.      endflag := false; done := false;
  71.      i := 0;
  72.      while (i < 512) and not done do
  73.           begin
  74.           inc(i);
  75.           if buf[i] = $1A then
  76.                begin
  77.                endflag := true;
  78.                done := true;
  79.                if length(s) > 0 then ok := memo.append(s+chr($FE));
  80.                end
  81.           else if buf[i] = $0A then
  82.                begin
  83.                s := s + chr($8A);
  84.                ok := memo.append(s);
  85.                s := '';
  86.                end
  87.           else s := s + chr(buf[i]);
  88.           end;
  89.      end;
  90.  
  91.  
  92.  
  93. {SECTION  PrepareSTRAforOutput }
  94. Procedure PrepareSTRAforOutput(var memo : STRA_object);
  95. var s    : string;
  96.     by   : byte;
  97.     i    : integer;
  98.      begin
  99.      if memo.count = 0 then   { if empty memo, just put end-marker }
  100.           begin
  101.           s := chr($FE);
  102.           memo.append(s);
  103.           exit;
  104.           end;
  105.  
  106.      for i := 1 to memo.count do
  107.           begin
  108.           s := memo.fetchN(i);
  109.           by := byte(s[length(s)]);
  110.           if  by <> $8A then
  111.                begin
  112.                s := s + chr($8D) + chr($8A);
  113.                memo.storeN(i,s);
  114.                end;
  115.           if i = memo.count then
  116.                begin
  117.                s := memo.fetchN(i);
  118.                by := byte(s[length(s)]);
  119.                if  by <> $FE then
  120.                     begin
  121.                     s := s + chr($FE);
  122.                     memo.storeN(i,s);
  123.                     end;
  124.                end;
  125.           end;
  126.      end;
  127.  
  128.  
  129. {SECTION  LoadBuffromSTRA }
  130. Function LoadBuffromSTRA(var buf : MEMObuftype; var memo : STRA_object;
  131.                     var endflag : boolean; var ii,jj : integer):boolean;
  132. { need to be handed an initialized STRA object, ii & jj can point to middle
  133.    of STRA from a previous buffer. Calling program sets ii,jj := 0; first time}
  134. var k         : integer;
  135.     s         : string;
  136.     by        : byte;
  137.      begin
  138.      k := 1;
  139.      LoadBuffromSTRA := false;
  140.      endflag := true;
  141.      fillchar(buf,sizeof(buf),0);
  142.      if memo.count = 0 then exit;
  143.      while ii < memo.count do
  144.           begin
  145.           inc(ii);
  146.           s := memo.fetchN(ii);
  147.           while jj < length(s) do
  148.                begin
  149.                inc(jj);
  150.                by := byte(s[jj]);
  151.                if      by = $8A then buf[k] := $0A
  152.                else if by = $FE then buf[k] := $1A
  153.                else                  buf[k] := by;
  154.                inc(k);
  155.                if k > mblksize then
  156.                     begin
  157.                     dec(ii); { so we can finish the line next time}
  158.                    { writeln('RETURNING PART buffer ',ii,' ',jj,' ',k);}
  159.                     LoadBuffromSTRA := true;
  160.                     endflag := false;
  161.                     exit;
  162.                     end;
  163.                end;
  164.           jj := 0;
  165.           end;
  166.     { writeln('RETURNING LAST buffer ',ii,' ',jj,' ',k);}
  167.      LoadBuffromSTRA := true;
  168.      end;
  169.  
  170.  
  171. Function MemoBlocksNeeded(var memo : STRA_object) : integer;
  172. var blocks,ii,jj : integer;
  173.     endflag      : boolean;
  174.     buf          : MEMObuftype;
  175.      begin
  176.      ii := 0; jj := 0; blocks := 0; endflag := false;
  177.      fillchar(buf,sizeof(buf),0);
  178.      while not endflag do
  179.          begin
  180.          if LoadBuffromSTRA(buf,memo,endflag,ii,jj) then inc(blocks);
  181.          end;
  182.      MemoBlocksNeeded := blocks;
  183.      end;
  184.  
  185.  
  186. {SECTION MEMO_object }
  187.  
  188. Procedure MEMO_object.init(fname : string; dbfmode : integer);
  189. var create : boolean;
  190.      begin
  191.      opened := false; recs := 1; err := 0;
  192.      create := false;
  193.      if dbfmode = fCREATE then create := true;
  194.      fillchar(mbuf,sizeof(mbuf),0);
  195.      BFILE_object.InitWithHdr(fname,mblksize,mblksize,dbfmode);
  196.      if create then
  197.           begin
  198.           UpDateHeader;
  199.           UpDateHeader; {since UpdateHeader does filesize, do it twice}
  200.          { writeln('memo object create ',recs);}
  201.           if not NoError then writeln('UpdateHeader error ',err);
  202.           end;
  203.      if NoError then
  204.           ReadHeader
  205.      else writeln('BFILE_object err ',err);
  206.      end;
  207.  
  208.  
  209. Procedure MEMO_object.ReadHeader;
  210.      begin
  211.      if hdrptr = NIL then
  212.          begin
  213.          writeln('PbMEMO BFILE header problem ');
  214.          exit;
  215.          end;
  216.      BFILE_object.ReadHeader;
  217.      if not NoError then writeln('ReadHeader error ',err);
  218.      move(hdrptr^,recs,4);
  219.    {  writeln('ReadHeader ',recs);}
  220.      end;
  221.  
  222.  
  223. Procedure MEMO_object.UpdateHeader;
  224.      begin {NOTE: A4 only writes for the actual length of the memo,
  225.                    so the last block is always partial and the intervening
  226.                    space is garbage.  I always write full blocks.}
  227.      if hdrptr = NIL then
  228.          begin
  229.          writeln('PbMEMO BFILE header problem ');
  230.          exit;
  231.          end;
  232.      recs := (filesize(fil)+(mblksize-1)) div mblksize;
  233.      move(recs,hdrptr^,4);
  234.      BFILE_object.UpdateHeader;
  235.      end;
  236.  
  237.  
  238.  
  239. Function  MEMO_object.fetchN( ndx : MemoNdx; var memo : STRA_object;
  240.                                 var blocks : integer) : boolean;
  241. var eorflag,ok : boolean;
  242.     i            : integer;
  243.     holder       : string;
  244.      begin
  245.      err := 0;
  246.      holder := '';
  247.      eorflag := false;
  248.      ok := true;
  249.      i := 0;
  250.      blocks := 0;
  251.      if ndx >= recs then
  252.           begin
  253.           fetchN := false;
  254.           err    := 1;
  255.           exit;
  256.           end;
  257.      while not eorflag and ok do
  258.           begin
  259.           if BFILE_object.fetchN(ndx+i,mbuf) then
  260.                begin
  261.                LoadSTRAfromBuf(mbuf,memo,eorflag,holder);
  262.                inc(i);
  263.                blocks := i;
  264.                end
  265.           else ok := false;
  266.           end;
  267.      fetchN := ok;
  268.      end;
  269.  
  270.  
  271. Function  MEMO_object.MemoBlocksN ( ndx : MemoNdx) : integer;
  272. var eorflag,ok : boolean;
  273.     i,j,blocks   : integer;
  274.      begin
  275.      err := 0;
  276.      MemoBlocksN := 0;
  277.      if ndx >= recs then exit;
  278.      if ndx < 1    then exit;
  279.      eorflag := false;
  280.      ok := true;  i := 0; blocks := 0;
  281.      while not eorflag and ok do
  282.           begin
  283.           if BFILE_object.fetchN(ndx+i,mbuf) then
  284.                begin
  285.                for j := 1 to mblksize do
  286.                    if mbuf[j] = $1A then eorflag := true;
  287.                inc(i);
  288.                blocks := i;
  289.                end
  290.           else ok := false;
  291.           end;
  292.      MemoBlocksN := blocks;
  293.      end;
  294.  
  295.  
  296.  
  297. Function  MEMO_object.storeN(var memo : STRA_object;
  298.                  var ndx : MemoNdx; var blocks : integer) : boolean;
  299. var needb, currb, i,ii,jj, bnum : integer;
  300.     endflag : boolean;
  301.      begin
  302.      err := 0;
  303.      PrepareSTRAforOutput(memo);
  304.      currb := MemoBlocksN(ndx);
  305.      needb := MemoBlocksNeeded(memo);
  306. {     if needb > currb then
  307.           writeln('MEMO_object  - StoreN ',' mnum:',ndx:5,'  mlines:',memo.count,
  308.                   '  currb:',currb,'   needb:',needb); }
  309.      if needb > currb then ndx := -1;  {append}
  310.      ii := 0; jj := 0; blocks := 0; endflag := false;
  311.      while not endflag do
  312.           begin
  313.           fillchar(mbuf,sizeof(mbuf),0);
  314.           if LoadBuffromSTRA(mbuf,memo,endflag,ii,jj) then
  315.                begin
  316.                if ndx > 0 then bnum := ndx + blocks
  317.                else bnum := recs + blocks;
  318.               { writeln('writing MEMO curr:',recs,'  new:',bnum);}
  319.                BFILE_object.storeN(bnum,mbuf);
  320.                if err <> 0 then writeln('BFILE_object.storeN error ',err);
  321.                inc(blocks);
  322.                end;
  323.           end;
  324.      if ndx = -1 then ndx  := recs;   {first after old eof }
  325.      UpdateHeader;                    {update header to new size}
  326.      storeN := NoError;
  327.      end;
  328.  
  329.  
  330. Function  MEMO_object.append(var memo : STRA_object;
  331.                  var ndx : MemoNdx; var blocks : integer) : boolean;
  332. var needb : integer;
  333.      begin
  334.      err := 0;
  335.      ndx := -1;
  336.      append := storeN(memo,ndx,blocks);
  337.      end;
  338.  
  339.  
  340.  
  341. Procedure MEMO_object.done;
  342.      begin
  343.      BFILE_object.done;
  344.      end;
  345.  
  346.  
  347. {SECTION  zzMEMOInit }
  348. Procedure zzMEMOInit;
  349.      begin
  350.      end;
  351.  
  352.  
  353. {SECTION  ZInitialization }
  354.      begin {Initialization}
  355.      zzMEMOinit;
  356.      end.
  357.